מבני נתונים תרגיל 5 תאריך פרסום: תאריך הגשה: מרצה ומתרגל אחראים: צחי רוזן, תומר כהן נהלי הגשת עבודה: את העבודה יש להגיש בזוגות. את הפתרון לעבודה זו עליכם לכתוב בקובץ word )או כל כתבן אחר לפי טעמכם האישי(, עבודות הכתובות בכתב יד לא יתקבלו. את הקובץ יש להגיש למערכת ההגשה System).(Submission שאלות לגבי העבודה יש להעלות בפורום של הקורס או בשעות הקבלה של המרצה או המתרגל האחראיים על העבודה. נושאים:.Heap Graphs Sorting MST Union Find הערה כללית לגבי השאלות בעבודה: שימו לב כי בכל שאלה בה אתם מתבקשים להציע מימוש למבנה נתונים התומך בפעולות נתונות, עליכם לתת תיאור של מבנה הנתונים )האם למשל יורכב ממערך, שתי מחסניות, תור של רשימות ומשתנה וכד'...(. בנוסף, עליכם לתאר את האלגוריתמים לביצוע כל אחת מהפעולות המבוקשות.
מערך כמעט ממוין עם טווח k הוא מערך שכל איבר בו נמצא במרחק של לכל היותר k מקומות מהמקום בו הוא אמור היה להיות לו המערך היה ממוין..1 לדוגמא המערך הבא הוא כמעט ממוין בטווח אחד. 2 1 3 5 4 7 6 9 8 11 שכן, לו המערך היה ממוין )למטה(, כל איבר בו היה במרחק של לכל היותר מקום אחד ממקומו במערך הממוין. 1 2 3 4 5 6 7 8 9 11. תארו אלגוריתם למיון מערך כמעט ממוין בגודל n עם טווח k בזמן (( נעשה זאת בעזרת ערימה. האלגוריתם: איתחול 1= i. א. הכנס את k האיברים הראשונים לערימת מינימום. ב. כל עוד הערימה לא ריקה: ג. i. הוצא את האיבר המינימאלי מהערימה והכנס למערך במקום a. אם :i + k n הכנס את A[i+k] לערימה..b.i = i + 1.c ניתוח זמן ריצה: בניית הערימה - O(k) הכנסת והוצאת איבר מערימה : O(log(k)) חזרה על הלולאה n פעמים. סה"כ: O(nlog(k)) O(n*log(k)+k) =
נתון גרף מכוון ). תארו אלגוריתם אשר בהינתן קדקודים מוצא ב- G מסלול מ- s ל- t שאורכו מודול 3 שווה לאפס. זמן הריצה הנדרש: ). במידה ולא קיים מסלול כזה, על האלגוריתם להדפיס הודעה מתאימה..2 האלגוריתם יהיה דומה ל- BFS המתחיל בקדקוד s עם השינויים הבאים: בכל קדקוד v נחזיק מערך A בגודל 3 מאותחל באפסים. האינדקסים במערך יתחילו באפס. אם באיזשהו שלב A[i] יהיה שווה ל- 1, אזי יש מסלול מ- s ל- ל v שאורכו מודולו 3 שווה ל- i. האלגוריתם בודק אם באיזשהו שלב [0]A של הקדקוד t מקבל את הערך 1. אם כן יש מסלול מ- s ל- t שאורכו מודולו 3 שווה 0, אחרת אין. בנוסף, נחזיק בכל קדקוד v שדה d שיציין את אורך המסלול הנוכחי מודולו 3 מ- s ל- t בסריקת ה- DFS שלנו. האלגוריתם: 1 let Q be an empty queue 2 s.d = 0 3 s.a[s.d] = 1 4 Q.enqueue(s) 5 while Q is not empty 6 v Q.dequeue() 7 for all edges u in G.adj(v) do 8 if u.a[(v.d+1)%3] = 0 9 u.d = (v.d+1)%3 10 u.a[u.d] = 1 11 Q.enqueue(u) ניתוח זמן ריצה: כל קדקוד יכנס לתור לכל היותר 3 פעמים ובכל פעם עוברים על כל השכנים שלו לכן בדומה לBFS זמן הריצה יהיה O(V+E)
k. log(n) רצפים של מספרים עוקבים וש- k מ- מורכב מספרים שלמים. ידוע שA n הוא מערך של A כלומר קיימות k קבוצות מספרים שלמים מהצורה: { } { } { }.3 כך ש- n1+n2+ +nk=n ו- A מכיל את איחוד הקבוצות. שימו לב. הקבוצות לא בהכרח זרות והן אינן מופיעות בהכרח כרצפים ממוינים במערך A. אם ערך מסוים מופיע במספר קבוצות, הוא יופיע במערך A מספר פעמים כמספר הקבוצות בהן הוא מופיע. למשל המערך 4] A=[11, 3, 2, 13, 4, 6, 12, 5, מקיים את התנאים הנדרשים עבור = 3 k והקבוצות } {, } { ו- } { הציעו אלגוריתם למיון A בזמן ריצה קצר ככל האפשר, והוכיחו חסם הדוק לזמן הריצה של האלגוריתם שלכם. כדי לפתור את השאלה נשים לב שכל מערך Arr של O(n) מספרים שלמים אשר מקיים: ) ) ) ).) ) ניתן למיון בעזרת מיון מניה בזמן O(n) )פשוט צריך להחסיר מכל איבר ב- Arr את בפתרון נשתמש בעובדה זו ונמיין בעזרת מיון מניה קבוצות של מספרים המקיימות את התנאי. מקיימים את התנאי. אברי הקבוצה ) נסתכל על המערךA. נניח ללא הגבלת הכלליות כי ואת כל האיברים הגדולים בזמן O(n) ע"י כך שנמצא את ) )*(. ניתן למצוא ב- A את כל אברי בזמן.O(n) את האיברים האלה אנחנו יכולים למיין במיון מניה בזמן O(n). אחרי ) שווים מ- שעשינו זאת אנו יכולים לחזור על הפעולה שוב ושוב בזמן O(n), כאשר בכל פעם אנחנו מפרידים וממיינים קבוצת איברים המכילה בתוכה את הקבוצה Si אשר מכילה את האיבר המקסימלי מבין האיברים. A שנותרו ב- Sort-Them(A) i = 0 While A is not empty do i=i+1 Put all the numbers in A in the ) ) range in array A = New array containing = sorted in O(n) time using modified counting sort. C = new array containing in order {,, } האלגוריתם בבירור ממיין את A משום שהוא בכל פעם לוקח קבוצה שמכילה את כל המספרים מעל גודל מסוים,ממיין אותם, ובסוף מסדר את המערכים הממוינים לפי טווחי הערכים.
ניתוח זמן ריצה: האלגוריתם רץ ב- O(nk) זמן משום שלולאת ה- While נפטרת בכל איטרציה לפחות מאחת מהקבוצות Siולכן רצה k פעמים לכל היותר, וגוף לולאת ה- While מורכב ממספר סופי של פעולות שזמן הריצה שלהם חסום ע"י( O(n.
הוא 2 צביע אם ניתן לצבוע את קדקודיו בשני צבעים כך שלכל צלע גרף לא מכוון ) ) מתקיים ) ) דוגמא:.4 גרף זה לא 2 צביע כי לא ניתן לצבוע את הקודקוד הלבן בירוק או כחול כך שהצביעה תהיה חוקית גרף זה 2 צביע, כי מצאנו צביעה חוקית. א( ב( ג( הראו שאם גרף מכיל מעגל באורך אי זוגי אזי גרף זה לא 2 צביע. הראו שגרף לא מכוון וקשיר חסר מעגלים )עץ( הינו 2 צביע. תנו הסבר מפורט. הציעו אלגוריתם שצובע עץ בשני צבעים: לבן ושחור. מה זמן ריצתו הציעו אלגוריתם שמקבל גרף לא מכוון וקשיר וקובע האם הגרף הינו 2 צביע או לא. א( ב( נניח בשלילה כי ניתן לצבוע את הגרף ב- 2 צבעים, נביט על מעגל חייב להיות צבוע בצבע 2,, ) בצבע 1, מכיוון ש ) צבוע בצבע 1, אך המעגל הוא אי-זוגי נקבל כי סתירה(. נראה זאת באינדוקציה: אי זוגי בגרף. צבוע בצבע 1 וכך הלאה. מכיוון שאורך לכן הצביעה אינה חוקית )כלומר בסיס: לכל הטענה ברורה.,T = T/ הנחה: נניח כי ניתן לצבוע עץ בעל 1-n קודקודים צעד: נביט על T עץ בעל n קודקודים. מכיוון ש T הוא עץ קיים לו לפחות עלה אחד )בעל דרגה 1( נסמנו, נביט על T עדיין עץ והוא בעל 1-n קודקודים, לכן לפי ההנחה ניתן לצבוע אותו ב- 2 צבעים. כעט נביט על, מחובר אליו. הוא עלה ולכן מחובר רק לקודקוד אחד, נצבע את בצבע ההפוך לקודקוד שהוא האלגוריתם: נפעיל,BFS לכל קודקוד שמרחקו זוגי מהשורש ניתן את הצבע 1, ולכל קודקוד שמרחקו איזוגי ניתן את הצבע 2.
נכונות האלגוריתם : נניח בשלילה שחזרה צביעה לא חוקית נניח בה"כ כי קיימת קשת בין זוגית ל מרמה אי זוגית, לכן קיים מסלול באורך זוגי מהשורש ל וגם מסלול זוגי ל )עד ל ל ) לכן קיים מעגל בגרף סתירה. מרמה אי ואז זמן ריצה:,O(V+E) = BFS לעבור על קודקודים.O(V) סה"כ O(V+E) ג( האלגוריתם יהיה BFS עם שינוי קל: כאשר נקבע את המרחק, שנסמנו d, של קודקוד מהשורש, נבדוק את כל השכנים של הקודקוד, אם קיים שכן שגילינו כבר בסריקה שמרחקו )r<d( r כך ש d%2 = r%2 נחזיר שאי אפשר לצבוע עם 2 צבעים, אחרת נמשיך בסריקת ה,BFS אם הגענו לסוף הסריקה נחזיר שניתן לצבוע את הגרף עם 2 צבעים. נכונות האלגוריתם: קל לראות כי אם יש מסלול זוגי ואי זוגי מהשורש לקודקוד מסוים קיים מעגל אי זוגי בגרף, ולכן לא צביע. אם סיימנו את האלגוריתם אז ניתן לכל קודקוד את הצבע ) ( ומכיוון שאין שכנים שהמרחק שלהם מהשורש מודולו 2 שווה קיבלנו צביעה חוקית. קוטר של גרף הינו אורך המסלול הפשוט הארוך ביותר בגרף )מסלול פשוט מסלול ללא חזרות על קדקודים, להוציא אולי את הקדקודים בשתי קצוות המסלול(. תארו אלגוריתם שבהינתן עץ מחזיר את קוטר הגרף. זמן ריצה נדרש: ).5 ראשית נשים לב לעובדה כי אם המרחק בין ל הוא המרחק הגדול ביותר בגרף, כאשר נפעיל את האלגוריתם BFS על או בתור שורש נקבל כי המרחק המקסימאלי שהאלגוריתם יתן הוא הקוטר. האלגוריתם: a. בחר קדקוד.b.c.d.e הפעל BFS מ מצא את הקדקוד בגרף. הרחוק ביותר מ- הפעל BFS מ החזר את המרחק הגדול ביותר. נכונות האלגוריתם: נניח כי המרחק המקסימאלי הוא בין הרחוק ביותר מ נראה כי המרחק בין ל או בין ל ל ונניח כי האלגוריתם מצא כי הוא הגדול ביותר. הוא, נביט על המסלול מהשורש ל נסמנו, ועל המסלול בין נסמנו ל.) נשים לב כי, )מכיוון שאחרת נוכל לקבל מסלול ארוך יותר מהמסלול בין ל
, )כי אחרת ארוך לפחות כמו, נבחין כי במקרה זה המסלול יותר קרוב ל בה"כ הוא לפחות באורך נקבל מסלול ארוך יותר מהשורש בניגוד להנחה(, לכן המסלול הוא הגדול ביותר בעץ. ל ולכן נקבל שהמרחק בין ל המסלול בין זמן ריצה: הפעלה פעמיים של,O(E+V) : BFS חיפוש קדקוד עם מרחק מקסימאלי:.O(V) סה"כ: O(E+V) העשרה: עץ על הקשתות הוא גרף מיוחד אם יש ל- G עם פונקציית משקל נאמר שגרף ) על הקשתות ובודק אם עם פונקציית משקל פורש מינימלי (MST) יחיד. תארו אלגוריתם המקבל כקלט גרף ) G הוא גרף מיוחד. על האלגוריתם להחזיר את העץ הפורס המינימלי היחיד שלG, אם G הוא גרף מיוחד, או אחרת על האלגוריתם להודיע שהגרף אינו מיוחד.. זמן הריצה הנדרש: ((.6 גרף G הוא מיוחד אם לא קיים עץ פורש מינימאלי נוסף. האלגוריתם: 1 A = 2 curr = - 2 foreach (u,v) in G.E: 3 (u,v).color = white 4 foreach v G.V: 5 MAKE-SET(v) 6 foreach (u, v) ordered by weight(u, v), increasing: 7 if weight(u,v) > curr: 8 curr = weight(u,v) 9 foreach (u,v ) s.t. weight(u,v)=weight(u,v ): 10 if FIND-SET(u ) FIND-SET(v ): 11 (u,v ).color = grey 12 if FIND-SET(u) FIND-SET(v): 13 (u,v).color = white 14 A = A {(u, v)} 15 UNION(u, v)
16 foreach (u,v) in G.E: 17 if (u,v).color = grey: 18 return false 19 return A נכונות האלגוריתם: ניזכר כי האלגוריתם של קרוסקל כל פעם בוחר את הקשת הקלה ביותר שאפשר להוסיף. נשים לב כי אם קיימות 2 קשתות באותו משקל ששתיהן בטוחות בעת הוספת אחת מהקשתות, אך לאחר הוספת אחת מהקשתות, הקשת השניה אינה בטוחה, האלגוריתם של קרוסקל היה נותן פתרון אחר אם היינו בוחרים את הצלע השניה. ולכן קיים עוד עץ פורש כלומר G איננו מיוחד. כעט נותר להראות כי אם יש 2 עצי MST )שאחד מהם נוצר ע"י קרוסקל( אז קיימות 2 צלעות כנ"ל. יהי שני העצים, תהי הצלע הקלה ביותר ב שאינה ב ו הצלע הקלה ביותר ב שאינה ב. נראה כי משקל שווה למשקל. נניח בשלילה שהם לא שוות, בה"כ היא הקלה יותר. נוסיף את ל כעט יש מעגל ב נשים לב כי לא יכול להיות כי כל הצלעות במעגל קטנות ממש מ כי אז קייימת צלע במעגל שלא שייכת ל ואז נקבל סתירה להנחה ש היא הקלה יותר, בנוסף לא יכול להיות שיש צלע יותר כבדה מ כי אז נוציא אותה ונקבל עץ ששוקל פחות. לכן קיימת צלע במעגל ששוקלת כמו ואינה ב בסתירה לכך ש הצלע הקלה ביותר ב שאינה ב. ניתוח זמן ריצה: האלגוריתם מבוסס על קרוסקל לכן די שננתח רק את מה שהוספנו. הלולאה בשורה 2 עוברת על כל הקשתות O(E) הלולאה בשורה 9 עוברת על כל קשת לכל היותר פעם אחת וכל הפעלה לוקחת log(v) לכן סה"כ O(Elog(V)) הלולאה בשורה 16 עוברת על כל הקשתות O(E) O(Elog(V)) = O(Elog(V)) + O(E) + O(E) לכן סה"כ זמן ריצה : זמן של קרוסקל +
תארו אלגוריתם הממיין n נקודות שנדגמו בצורה אחידה )יוניפורמית( ממישור היחידה באורך n )המלבן שהנקודה השמאלית העליונה שלו היא (1,0) והנקודה הימנית התחתונה שלו היא (1-,n)(. על המיון למיין את הנקודות לפי מרחקן מראשית הצירים. על המיון לעבוד בזמן ממוצע )צפי( של.O(n).7 רמז: חישבו איך אפשר לחלק את מישור היחידה לקטעים רלוונטיים למיון, כך שהשטח של כל אחד מהם )להוציא אולי קטע אחד( הוא סדר גודל של n/1 מהשטח הכולל של מישור היחידה בגודל n )כפי שהוגדר למעלה( נשתמש במיון דליים כאשר החלוקה לדליים היא לפי המרחק מהראשית. נקודה שנמצאת בתוך מעגל היחידה שייכת לדלי מס' 1. נקודה שנמצאת בתוך מעגל בעל רדיוס i אבל מחוץ למעגל בעל רדיוס 1-i שייכת לדלי מס'. i סה"כ 1+n דליים. כל שצריך להראות הוא שהשטח שכל דלי מכסה )להוציא הדלי שמכסה את השטח הרחוק ביותר מהראשית(, הוא בסדר גודל של n/1 מהשטח שממנו נדגמו הנקודות. אבל. גודל השטח ממנו נדגמו הנקודות הוא בגודל של n*2, ושטח כל דלי אינו עולה על 4=2*2 ואינו נופל מ- pi/4 ולכן בסדר גודל של.1/n